package com.example.juejincheck.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.ECDSAKeyProvider;
import org.apache.commons.io.IOUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.spec.SecretKeySpec;
import java.io.InputStream;
import java.security.*;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

public class JwtUtils {

    public static String secretKey = "-----BEGIN EC PARAMETERS-----\n" +
            "BggqhkjOPQMBBw==\n" +
            "-----END EC PARAMETERS-----\n" +
            "-----BEGIN EC PRIVATE KEY-----\n" +
            "MHcCAQEEIDB7KMVQd+eeKt7AwDMMUaT7DE3Sl0Mto3LEojnEkRiAoAoGCCqGSM49\n" +
            "AwEHoUQDQgAEEkViJDU8lYJUenS6IxPlvFJtUCDNF0c/F/cX07KCweC4Q/nOKsoU\n" +
            "nYJsb4O8lMqNXaI1j16OmXk9CkcQQXbzfg==\n" +
            "-----END EC PRIVATE KEY-----";

    /**
     * 生成token
     * @return
     */
    public static String sign(Long time, String s) {
        Map<String, Object> header = new HashMap<>();
        header.put("alg", "ES256");
        header.put("typ", "JWT");
        Map<String, Object> payload = new HashMap<>();
        payload.put("gameId", s);
        payload.put("time", time);
        String jwtToken = JWT.create()
                // Header
                .withHeader(header)
                // Payload
                .withPayload(payload)
                .withClaim("algorithm", "ES256")
                .withClaim("expiresIn",2592000)
                // 签名用的secret
                .sign(Algorithm.ECDSA256(null, (ECPrivateKey) getECPrivateKey()));

        return jwtToken;
    }
    /**
     * 获取PrivateKey对象
     *
     * @return
     */
    private static PrivateKey getECPrivateKey() {
        try {
            Security.addProvider(new BouncyCastleProvider());
            KeyFactory keyFactory = KeyFactory.getInstance("ECDH", "BC");
            InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("crt/ec_private_pkcs8");
            byte[] devicePriKeybytes = IOUtils.toByteArray(inputStream);
            PKCS8EncodedKeySpec devicePriKeySpec = new PKCS8EncodedKeySpec(devicePriKeybytes);
            return keyFactory.generatePrivate(devicePriKeySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取PublicKey对象
     *
     * @return
     */
    private static PublicKey getECPublicKey() {
        try {
            Security.addProvider(new BouncyCastleProvider());
            KeyFactory keyFactory = KeyFactory.getInstance("ECDH", "BC");

            InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("crt/ec_public.pem");
            String publicKeyBase64 = IOUtils.toString(inputStream, "UTF-8");

            publicKeyBase64 = publicKeyBase64.replaceAll("\\-*BEGIN.*KEY\\-*", "")
                    .replaceAll("\\-*END.*KEY\\-*", "")
                    .replaceAll("\r", "")
                    .replaceAll("\n", "");
            byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyBase64);

            X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(publicKeyBytes);
            return keyFactory.generatePublic(pubX509);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJnYW1lSWQiOiIyMDIyLTEyLTA3IDE1OjMwOjMwICswODowMCIsInRpbWUiOiIxNjcwMzk4MjM5ODI1IiwiaWF0IjoxNjcwMzk4MjM5LCJleHAiOjE2NzI5OTAyMzl9.9M2WPGDzVv2cgWzRb9mukTUTLL0O58QxEsbmOIY45EUCgJHYX2xESWKOMTTzaV7O5DippbMGA-t8vPNP47irEQ
    public static void main(String[] args) {
        System.out.println(sign(1670398239825L, "2022-12-07 15:30:30 +08:00"));
    }
}
